home *** CD-ROM | disk | FTP | other *** search
- #include <bios.h>
- #include <go32.h>
- #include <dpmi.h>
- #include <stdlib.h>
-
- #define tb _go32_info_block.linear_address_of_transfer_buffer
-
- static int dos_segment = 0;
- static _go32_dpmi_seginfo dos_info;
-
- static void free_dos_buffer()
- {
- _go32_dpmi_free_dos_memory(&dos_info);
- dos_segment = 0;
- }
-
- static void alloc_dos_buffer()
- {
- if (dos_segment)
- return;
- dos_info.size = 18 * 512 / 16;
- if (_go32_dpmi_allocate_dos_memory(&dos_info))
- {
- dos_segment = 0;
- return;
- }
- dos_segment = dos_info.rm_segment;
- atexit(free_dos_buffer);
- }
-
- int biosdisk(int cmd, int drive, int head, int track,
- int sector, int nsects, void *buffer)
- {
- int seg, ofs, xfer=0, before=0;
- _go32_dpmi_registers r;
- switch (cmd)
- {
- case 2:
- xfer = 512 * nsects;
- before = 0;
- break;
- case 3:
- xfer = 512 * nsects;
- before = 1;
- break;
- case 5:
- xfer = 2 * 256;
- before = 1;
- break;
- case 0x0a:
- xfer = (512+7) * nsects;
- before = 0;
- break;
- case 0x0b:
- xfer = (512+7) * nsects;
- before = 1;
- break;
- case 0x0e:
- xfer = 512;
- before = 0;
- break;
- case 0x0f:
- xfer = 512;
- before = 1;
- break;
- }
- if (xfer)
- {
- if (xfer > 18*512)
- return 1; /* bad command */
- if (xfer > _go32_info_block.size_of_transfer_buffer)
- {
- alloc_dos_buffer();
- if (dos_segment == 0)
- return 0xbb; /* undefined error */
- seg = dos_segment;
- ofs = 0;
- }
- else
- {
- seg = tb >> 4;
- ofs = tb & 15;
- }
- }
- memset(&r, 0, sizeof(r));
- r.h.ah = cmd;
- r.h.al = nsects;
- r.x.es = seg;
- r.x.bx = ofs;
- r.h.ch = track & 0xff;
- r.h.cl = sector | ((track >> 2) & 0xc0);
- r.h.dh = head;
- r.h.dl = drive;
- if (xfer && before)
- dosmemput(buffer, xfer, seg*16+ofs);
- _go32_dpmi_simulate_int(0x13, &r);
- if (xfer && !before)
- dosmemget(seg*16+ofs, xfer, buffer);
- if (cmd == 0x08)
- {
- ((short *)buffer)[0] = r.x.cx;
- ((short *)buffer)[1] = r.x.dx;
- }
- return r.h.ah;
- }
-